﻿using System;
using System.Collections.Generic;

namespace ExtensionMethodExtravaganza
{
	public static class DictionaryExtensions
	{
		/// <summary>
		/// Gets the value for the specified key. If the key doesn't exist, a new
		/// instance of type V is created and added to the dictionary.
		/// </summary>
		public static V GetOrCreate<K, V>(this Dictionary<K, V> dictionary, K key) where V : new()
		{
			V value;

			if (!dictionary.TryGetValue(key, out value))
			{
				value = new V();
				dictionary.Add(key, value);
			}

			return value;
		}

		/// <summary>
		/// Gets the value for the specified key, if it exists in the dictionary. If it does
		/// not exist, it calls the method specified by <paramref name="lookup"/> and stores
		/// that value -- even if its null -- in the dictionary.
		/// </summary>
		public static V GetOrLookUp<K, V>(this Dictionary<K, V> dictionary, K key, Func<K, V> lookup)
		{
			V value;

			if (!dictionary.TryGetValue(key, out value))
			{
				value = lookup(key);
				dictionary.Add(key, value);
			}

			return value;
		}

		/// <summary>
		/// Gets the value for the specified key, if it exists in the dictionary. If it does
		/// not exist, the default value for <typeparamref name="V"/> is returned.
		/// </summary>
		public static V GetOrDefault<K, V>(this Dictionary<K, V> dictionary, K key)
		{
			V value;

			if (!dictionary.TryGetValue(key, out value))
			{
				value = default(V);
			}

			return value;
		}

		/// <summary>
		/// If the dictionary does not contain an item keyed with <paramref name="key"/>, the
		/// value returned by the <paramref name="lookup"/> method is added to the dictionary --
		/// even if it is null
		/// </summary>
		public static void AddIfDoesNotExist<K, V>(this Dictionary<K, V> dictionary, K key, Func<K, V> lookup)
		{
			if (!dictionary.ContainsKey(key))
			{
				dictionary.Add(key, lookup(key));
			}
		}

	}
}
